/**
 * 
 */
package com.repository.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.repository.exception.ApplicationException;
import com.repository.model.User;
import com.repository.service.UserRepositoryService;

/**
 * Main UserRepositoryService end-point. This handles all request that flows into the system.
 * @author lovkeshsingh
 *
 */
@Controller
public class UserRepositoryServiceController {

	@Autowired
	UserRepositoryService userRepositoryService;

	/**
	 * Returns {@link User} by user id
	 * @param id
	 * @return {@link User}
	 */
	@RequestMapping(value="/user/{id}", method=RequestMethod.GET)
	@ResponseBody 
	public User getUserDetails(@PathVariable Long id){

		User user = userRepositoryService.getUserById(id);

		if(null != user){
			return user;
		}else{
			throw new RuntimeException("User not found"); 
		}
	}

	/**
	 * Creates new {@link User} 
	 * @param userName
	 * @param password
	 * @return redirects to appropriate Handler method
	 */
	@RequestMapping(value="/user/{userName}/{password}", method=RequestMethod.POST)
	public String addUser(@PathVariable String userName, @PathVariable String password){

		Long userId = userRepositoryService.addUser(userName, password);

		return "redirect:/user/"+userId;
	}

	/**
	 * Removes {@link User} from system
	 * @param id
	 * @return returns {@code User Deleted} message on success
	 */
	@RequestMapping(value="/user/{id}", method=RequestMethod.DELETE)
	public void removeUser(@PathVariable Long id, HttpServletResponse resp){

		userRepositoryService.removeUser(id);

		try {
			
			resp.sendError(HttpServletResponse.SC_OK);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	/**
	 * Updates a {@link User}
	 * @param id
	 * @param userName
	 * @param password
	 * @return redirect to appropriate handler method
	 */
	@RequestMapping(value="/user/{id}/{userName}/{password}", method=RequestMethod.PUT)
	public String updateUser(@PathVariable Long id, @PathVariable String userName, @PathVariable String password){

		Long userId = userRepositoryService.updateUser(id, userName, password);

		return "redirect:/user/"+userId;
	}

	@RequestMapping("/exception")
	public void checkException() throws Exception{
		throw new Exception();
	} 

	/**
	 * ExceptionHandler method for all custom exceptions. It returns suitable error
	 * code 
	 * @param appEx
	 * @param resp
	 */
	@ExceptionHandler(ApplicationException.class)
	public void handleException(ApplicationException appEx, HttpServletResponse resp){

		try {
			
			resp.sendError(HttpServletResponse.SC_BAD_REQUEST, appEx.getMessage());
			
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	/**
	 * ExceptionHandler method for all Runtime exceptions. It returns suitable error
	 * code 
	 * @param appEx
	 * @param resp
	 */
	@ExceptionHandler(RuntimeException.class)
	public void handleException(Exception ex, HttpServletResponse resp){

		try {
			
			resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Some error in system");
			
		} catch (IOException e) {

			e.printStackTrace();
		}
	}


}
